package emby.expr;

import emby.err.TypeError;
import emby.lang.Block;
import emby.lang.EmbyFunction;
import emby.lang.Scope;
import emby.overload.OverloadCallable;
import emby.writer.IEmbyCodifier;

public class GenericBlock extends Expression {
	
	Expression wrapper_fn;
	Expression[] operands;
	Variable[] block_args;
	Block body;
	
	public GenericBlock(Expression wrapper_fn, Expression[] operands,
			Variable[] block_args, Block body){
		this.wrapper_fn = wrapper_fn;
		this.operands = operands;
		this.block_args = block_args;
		this.body = body;
	}

	@Override
	public Object eval(Scope s) {
		// TODO Auto-generated method stub
		EmbyFunction lambda = LambdaExpression.generateLambda(LambdaExpression.generateLambdaName(this)
								, s, body, block_args);
		//System.out.println("WRAPPER:"+wrapper_fn);
		Object op = wrapper_fn.eval(s);
		OverloadCallable f = null;
		if( op instanceof OverloadCallable){
			f = (OverloadCallable) op;
		}else{
			throw new TypeError(wrapper_fn.getLine(),op+" is not callable");
		}
		
		//eval the operands
		Object[] args = new Object[operands.length+1];
		args[0] = lambda;
		for(int i = 1; i< args.length; i++){
			args[i] = operands[i-1].eval(s);
		}

		//call the operator with the operands
		Object result = f.execute(getLine(),s,args);
		
		return result;
	}

	@Override
	public void codify(IEmbyCodifier ec) {
		// TODO Auto-generated method stub

	}

}
